package dev.tools;

import dev.tools.compiler.DynamicCompiler;
import dev.tools.utils.AppUtils;

import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;

public class DevToolsAgent {

    private static Instrumentation inst;

    public static void main(String args, Instrumentation inst) {
        DevToolsAgent.inst = inst;
    }

    public static void redefine(String newCode) throws Exception {
        if (inst == null || !inst.isRedefineClassesSupported()) {
            return;
        }
        String className = AppUtils.getClassName(newCode);
        Class clazz;
        if ((clazz = getClass(className)) != null) {
            DynamicCompiler dynamicCompiler = new DynamicCompiler(clazz.getClassLoader());
            dynamicCompiler.addSource(className, newCode);

            ClassDefinition classDefinition = new ClassDefinition(clazz, dynamicCompiler.buildByteCodes().get(clazz.getName()));
            inst.redefineClasses(classDefinition);
            return;
        }
        throw new IllegalStateException("The class are not found in the JVM and may not be loaded");
    }

    public static Class getClass(String className) {
        for (Class<?> clazz : inst.getAllLoadedClasses()) {
            if (clazz.getName().equals(className)) {
                return clazz;
            }
        }
        return null;
    }

    public static void premain(String args, Instrumentation inst) {
        main(args, inst);
    }

    public static void agentmain(String args, Instrumentation inst) {
        main(args, inst);
    }
}
